/**************************************************************************//**
 * @file     uart.c
 * @version  V1.00
 * $Revision: 6 $
 * $Date: 15/06/10 11:59a $
 * @brief    NUC970 UART driver source file
 *
 * @note
 * SPDX-License-Identifier: Apache-2.0
 * Copyright (C) 2015 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nuc970.h"
#include "nuc970_uart.h"

/** @addtogroup NUC970_Device_Driver NUC970 Device Driver
  @{
*/

/** @addtogroup NUC970_UART_Driver UART Driver
  @{
*/

/** @addtogroup NUC970_UART_EXPORTED_CONSTANTS UART Exported Constants
  @{
*/

/*@}*/ /* end of group NUC970_UART_EXPORTED_CONSTANTS */

/// @cond HIDDEN_SYMBOLS

/*-----------------------------------------*/
/* marco, type and constant definitions    */
/*-----------------------------------------*/

/*-----------------------------------------*/
/* global file scope (static) variables    */
/*-----------------------------------------*/

/*-----------------------------------------*/
/* prototypes of static functions          */
/*-----------------------------------------*/

static void Uart_Config(UART_HandleTypeDef *huart)
{
    UINT32 reg, divider;
    /* Check the supplied parity */
    if ( (huart->Parity != NUC_PARITY_NONE) &&
         (huart->Parity != NUC_PARITY_EVEN) &&
         (huart->Parity != NUC_PARITY_ODD)  &&
         (huart->Parity != (NUC_PARITY_ODD | NUC_PARITY_STICK)) &&
         (huart->Parity != (NUC_PARITY_EVEN | NUC_PARITY_STICK)) ) {
        return ;
    }

    /* Check the supplied number of data bits */
    if ( (huart->DataBits != NUC_DATA_BITS_5) &&
         (huart->DataBits != NUC_DATA_BITS_6) &&
         (huart->DataBits != NUC_DATA_BITS_7) &&
         (huart->DataBits != NUC_DATA_BITS_8) )
        return ;

    /* Check the supplied number of stop bits */
    if ( (huart->StopBits != NUC_STOP_BITS_1) &&
         (huart->StopBits != NUC_STOP_BITS_2) )
        return ;

    /* Check the supplied number of trigger level bytes */
    if ( (huart->Instance == UART1) || (huart->Instance == UART2) || (huart->Instance == UART4) ||
         (huart->Instance == UART6) || (huart->Instance == UART8) || (huart->Instance == UARTA)) {
        /* UART1,2,4,6,8,A */
    } else if ( (huart->Instance == UART0) || (huart->Instance == UART3) || (huart->Instance == UART5) ||
                (huart->Instance == UART7) || (huart->Instance == UART9)) {
        /* UART0,3,5,7,9 */
    } else {
        return;
    }

    divider = UART_BAUD_MODE2_DIVIDER(12000000, huart->BaudRate);

    if(divider > 0xFFFF)
        reg = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER(12000000, huart->BaudRate));
    else
        reg = (UART_BAUD_MODE2 | divider);

    huart->Instance->BAUD = reg;

    /* Setup parity, data bits, and stop bits */
    huart->Instance->LCR = (huart->Parity | huart->StopBits | huart->DataBits);
}

/// @endcond HIDDEN_SYMBOLS

/** @addtogroup NUC970_UART_EXPORTED_FUNCTIONS UART Exported Functions
  @{
*/
void Uart_Init(UART_HandleTypeDef *huart)
{
    huart->Instance->FCR = UART_FCR_TFR_Msk | UART_FCR_RFR_Msk;
    huart->Instance->ISR = 0xFFFFFFFF;

    Uart_Config(huart);

    /* Setup Rx time out value */
    huart->Instance->TOR = 0x40;

    /* Setup FIFO trigger level */
    if (huart->Instance == UART0 || huart->Instance == UART3 || huart->Instance == UART5 || 
        huart->Instance == UART7 || huart->Instance == UART9) {     // UART 0 3 5 7 9
        huart->Instance->FCR |= UART_FCR_RFITL_8BYTES;
    } else {                                                        // UART 1 2 4 6 8 10
        huart->Instance->FCR |= UART_FCR_RFITL_30BYTES;
    }
}

/*@}*/ /* end of group NUC970_UART_EXPORTED_FUNCTIONS */

/*@}*/ /* end of group NUC970_UART_Driver */

/*@}*/ /* end of group NUC970_Device_Driver */


/*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/
